package com.study.streamApi;

import com.study.methodcontrucet.Employee;
import com.study.methodcontrucet.EmployeeDataList;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @program: java8
 * @description: Stream的终端操作
 * @author: yangyb
 * @create: 2021-11-14 15:12
 **/
public class StreamApi3Test {
    /**
     * @Description: 匹配与查找
     * @Param: []
     * @return:
     */
    @Test
    public void test1() {
        List<Employee> employees = EmployeeDataList.getEmployees();
        //allMach(Predicate p) --检查是否匹配所有的元素(所有的是true 才是true)
        //eg：是否所有的员工的年龄都大于18岁
        boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 18);
        System.out.println(allMatch);
        //anyMach(Predicate p) --检查是否至少匹配一个元素元素(只有一个的是true 就是true)
        //eg:是否存在员工的工资大于10000的
        boolean anyMatch = employees.stream().anyMatch(employee -> employee.getSalary() > 10000);
        System.out.println(anyMatch);
        //noneMatch(Predicate p) --检查是否没有匹配的元素
        //eg:是否存在员工姓"雷"
        boolean noneMatch = employees.stream().noneMatch(employee -> employee.getName().startsWith("雷"));
        System.out.println(noneMatch);
        //findFirst()--返回第一个元素
        Optional<Employee> first = employees.stream().findFirst();
        System.out.println(first);
        //findAny()--返回当前流中的任意一个元素
        Optional<Employee> any = employees.parallelStream().findAny();
        System.out.println(any);


    }

    @Test
    public void test2() {
        List<Employee> employees = EmployeeDataList.getEmployees();
        //count()--返回流中元素的总个数
        long count = employees.stream().filter(employee -> employee.getSalary() > 199999).count();
        System.out.println(count);
        //max(Comparator c)--返回流中元素的最大值
        Optional<Double> max = employees.stream().map(e -> e.getSalary()).max(Double::compare);
        System.out.println(max);
        //min(Comparator c)--返回流中元素的最小值
        //eg:返回最低工资的员工
        Optional<Employee> employee = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(employee);
        //forEach(Consumer c)--内部迭代
        employees.stream().forEach(System.out::println);
        //使用集合的方式forEach()
        employees.forEach(System.out::println);


    }

    /**
     * @Description: 规约
     * @Param: []
     * @return:
     */
    @Test
    public void test3() {
        //reduce（T identity,BinaryOperator）--可以将流中反复结合起来(T identity:初始值)，得到一个值。返回
        //计算自然数1-10之和
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = list.stream().reduce(0, Integer::sum);
        //或者
        Integer integer = list.stream().reduce(0, (one, two) -> one + two);
        System.out.println(sum);
        //reduce（BinaryOperator)--可以将流中的元素反复结合起来，得到一个值。返回Optional<T>
        //计算员工工资总和
        List<Employee> employees = EmployeeDataList.getEmployees();
        Optional<Double> reduce = employees.stream().map(Employee::getSalary).reduce(Double::sum);
        System.out.println(reduce);

        System.out.println("########################");
        Double aDouble = Stream.of(-1.4, 4.6, -9.89).reduce(Double.MAX_VALUE, Double::min);
        System.out.println(aDouble);


    }

    /**
     * @Description: 收集
     * @Param: []
     * @return:
     */
    @Test
    public void test4() {
        //collect(Collector c)--收集：将流转换为其他形式。接受一个Collector接口的实现，用于给Stream中元素做汇总的方法。
        //collector 接口方法的实现决定了如何对流执行收集的操作（例如：收集到List、Set、Map）
        //另外，Collectors 实用类提供了很多静态方法，可以方便的创建常见收集器实例，具体方法与实例如下：
        //eg:查找工资大于6000的员工，结果返回为一个List(有序)或Set（无需）
        List<Employee> employees = EmployeeDataList.getEmployees();
        List<Employee> collect = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toList());
        collect.forEach(System.out::println);
        Set<Employee> employeeSet = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());
        employeeSet.forEach(System.out::println);


    }
}
